package com.wmx.guava;

import cn.hutool.core.date.DateUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.wmx.guava.pojo.Person;
import org.junit.Test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;

/**
 * Maps 专门为Map操作提供的工具类，它包含了大量静态方法，可以更简洁、更优雅的方式处理各种Map操作。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2025/9/27 上午10:20
 */
public class MapsTest {

    //===================ImmutableMap-不可变Map==========./start===================
    @Test
    public void testImmutableMap1() {
        // 快速创建不可变空Map
        Map<String, Integer> emptyMap = ImmutableMap.of();
        System.out.println(emptyMap); // {}
        // emptyMap.put("a", 1);// 如果尝试修改不可变map，则异常 java.lang.UnsupportedOperationException

        // 快速创建不可变Map(最多支持5对键值对)
        Map<String, Integer> immutableMap = ImmutableMap.of("Java", 1, "Python", 2, "Go", 3);
        System.out.println(immutableMap);// {Java=1, Python=2, Go=3}
        // immutableMap.put("a", 1); // 如果尝试修改不可变map，则异常 java.lang.UnsupportedOperationException

        Map<String, Object> immutableMap2 = ImmutableMap.of("Java", "A", "Python", 2, "Go", "3C", "C++", 4, "C#", 5);
        System.out.println(immutableMap2); // {Java=A, Python=2, Go=3C, C++=4, C#=5}

        // 使用Builder模式（超过5个键值对时推荐）
        Map<String, Object> complexMap = ImmutableMap.<String, Object>builder().put("Java", 1).put("Python", 2).put("Go", "3A").put("JavaScript", 4).put("C++", "5C").put("C#", "6#").build();
        System.out.println(complexMap);// {Java=1, Python=2, Go=3A, JavaScript=4, C++=5C, C#=6#}

    }
    //===================ImmutableMap-不可变Map==========./end===================

    enum Color {RED, GREEN, BLUE}

    /**
     * 创建特定类型的Map
     */
    @Test
    public void testMaps1() {
        // 创建EnumMap
        Map<Color, String> enumMap = Maps.newEnumMap(Color.class);

        // 创建IdentityHashMap
        Map<String, Integer> identityMap = Maps.newIdentityHashMap();

        // 创建TreeMap（带排序）
        Map<String, Integer> treeMap = Maps.newTreeMap();

        // 创建LinkedHashMap（保持插入顺序）
        Map<String, Integer> linkedMap = Maps.newLinkedHashMap();

        HashMap<String, Object> hashMap = Maps.newHashMap();

        // 如果知道大概的元素数量，预分配大小
        int expectedSize = 1000;
        Map<String, Integer> map = Maps.newHashMapWithExpectedSize(expectedSize);

        // 线程安全的 ConcurrentHashMap
        ConcurrentMap<Object, Object> objectObjectConcurrentMap = Maps.newConcurrentMap();
    }

    @Test
    public void testMaps2() {
        Map<String, Person> userMap = new HashMap<>();
        userMap.put("A1", new Person(1, "张三", DateUtil.parse("1999/08/01"), 15600.12F));
        userMap.put("B1", new Person(2, "李四", DateUtil.parse("1992/08/01"), 12600.40F));
        userMap.put("C1", new Person(3, "王五", DateUtil.parse("1998/08/01"), 14600.24F));

        // 转换值：从 Person 对象中提取用户名
        Map<String, String> nameMap = Maps.transformValues(userMap, Person::getName);
        System.out.println(nameMap); // {A1=张三, C1=王五, B1=李四}
    }

    /**
     * 计算Map差异
     */
    @Test
    public void testMaps3() {
        Map<String, Integer> oldScores = ImmutableMap.of("Alice", 80, "Bob", 90, "Age", 22);
        Map<String, Integer> newScores = ImmutableMap.of("Alice", 85, "Charlie", 90, "Age", 22);

        MapDifference<String, Integer> difference = Maps.difference(oldScores, newScores);

        System.out.println("相同的条目: " + difference.entriesInCommon()); // 相同的条目: {Age=22}
        System.out.println("左独有: " + difference.entriesOnlyOnLeft()); // 左独有: {Bob=90}
        System.out.println("右独有: " + difference.entriesOnlyOnRight()); // 右独有: {Charlie=90}
        System.out.println("值不同的条目: " + difference.entriesDiffering()); // 值不同的条目: {Alice=(80, 85)}
    }

    /**
     * 唯一索引：列表转Map的神器
     */
    @Test
    public void testMaps4() {
        List<Person> users = Arrays.asList(
                new Person(1, "张三", DateUtil.parse("1999/08/01"), 15600.12F),
                new Person(2, "李四", DateUtil.parse("1992/08/01"), 12600.40F),
                new Person(3, "王五", DateUtil.parse("1998/08/01"), 14600.24F));
        // 被转换后map的key不能重复，必须唯一，否则转换报错.
        ImmutableMap<Integer, Person> integerPersonImmutableMap = Maps.uniqueIndex(users, Person::getId);
        // {
        // 1=Person{id=1, name='张三', birthday=1999-08-01 00:00:00, salary=15600.12},
        // 2=Person{id=2, name='李四', birthday=1992-08-01 00:00:00, salary=12600.4},
        // 3=Person{id=3, name='王五', birthday=1998-08-01 00:00:00, salary=14600.24}
        // }
        System.out.println(integerPersonImmutableMap);
    }
}
